package org.zzk.handler;

import com.google.gson.JsonObject;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zzk.dao.*;
import org.zzk.util.MatchPool;

import org.zzk.util.RandomBooleanGenerator;

import java.util.Objects;

@ChannelHandler.Sharable
public class MatchRequestHandler extends SimpleChannelInboundHandler<ChessPacket> {
    public static final MatchRequestHandler INSTANCE = new MatchRequestHandler();
    private static final Logger logger = LoggerFactory.getLogger(MatchRequestHandler.class);
    private static final MatchPool matchPool = MatchPool.getInstance();

    // 客户端主动断开时触发（收到FIN包）
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("客户端主动断开连接: {}", ctx.channel().remoteAddress());
        Player player = matchPool.removePlayer(ctx.channel());
        if (player == null) {
            String roomId = RoomManager.getInstance().removeRoom(ctx.channel());
            if (!Objects.equals(roomId, "")) {
                logger.info("房间已删除: {}", roomId);
            }
        }

        super.channelInactive(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ChessPacket packet) {
        if (packet.getCommand() != CommandType.MATCH_REQUEST) { // 非匹配请求
            ctx.fireChannelRead(packet);
            return;
        }

        JsonObject data = packet.getData();
        String playerId = data.get("player_id").getAsString();
        int totalTime = data.getAsJsonObject("time_control").get("total").getAsInt();
        int stepTime = data.getAsJsonObject("time_control").get("step").getAsInt();

        boolean side = RandomBooleanGenerator.nextBooleanWithProbability(0.5);

        Player player = new Player(playerId, ctx.channel(), totalTime, stepTime, side);
        MatchResult result = matchPool.addPlayer(player, totalTime);

        JsonObject response = new JsonObject();
        if (result.isMatched()) {
            logger.info("matched");

            response.addProperty("status", "matched");
            response.addProperty("room_id", result.getRoomId());
            response.add("opponent", result.getOpponentInfo());
            ctx.writeAndFlush(new ChessPacket(CommandType.MATCH_SUCCESS, response));

            response.add("opponent", player.getPlayerInfo());
            result.getOpponent().getChannel().writeAndFlush(
                    new ChessPacket(CommandType.MATCH_SUCCESS, response));

        } else {
            response.addProperty("status", "waiting");
            ctx.writeAndFlush(new ChessPacket(CommandType.MATCH_SUCCESS, response));
        }
    }
}
